package com.slaffka.action;

import com.slaffka.model.Debtor;
import com.slaffka.model.Passport;
import org.richfaces.component.SortOrder;

import javax.faces.bean.ViewScoped;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.validation.ConstraintViolationException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: slaffka
 * Date: 17.11.12
 * Time: 0:00
 * To change this template use File | Settings | File Templates.
 */
@ViewScoped
@Named("debtorAction")
public class DebtorAction extends AbstractAction implements Serializable{

    @PersistenceContext
    private EntityManager entityManager;

    private DebtorListSort debtorListSort = new DebtorListSort();
    private int page = 1;
    private int rows = 20;
    private DebtorListFilter debtorListFilter = new DebtorListFilter();
    private Debtor debtorModel = new Debtor();

    private Boolean isUpdateMode = Boolean.FALSE;

//    public void prepareDebtorForUpdate(Debtor debtor){
//        debtorModel = debtor;
//
//        debtorModel.getPassportList();
//        isUpdateMode = Boolean.TRUE;
//    }

    public void resetDebtorModel(){
        debtorModel = new Debtor();
        isUpdateMode = Boolean.FALSE;
    }


    public void addOrUpdateDebtor(){
        if (debtorModel != null){
            try {
                debtorModel.setFirstName(debtorModel.getFirstName().trim());
                debtorModel.setLastName(debtorModel.getLastName().trim());
                debtorModel.setMiddleName(debtorModel.getMiddleName().trim());

                //предотвращаем detached entity passed to persist
                if (isUpdateMode || debtorModel.getDebtorId() != null){
                    entityManager.merge(debtorModel);
                } else {
                    entityManager.persist(debtorModel);
                }
                entityManager.flush();
                if (isUpdateMode){
                    msg = "Информация о занимателе успешно изменена";
                } else {
                    msg = "Заниматель " + debtorModel.getFIO() + " успешно заведен в справочник";
                }

                printInfo();
                resetDebtorModel();
            } catch (ConstraintViolationException e){
                msg = "заниматель " + debtorModel.getFIO() + " уже заведен в справочнике";
                printError(e);
            } catch (Exception e){
                if (isUpdateMode){
                    msg = "Операция изменения информации о занимателе выполнилась с ошибкой";
                } else {
                    msg = "Операция добавления занимателя с именем " + debtorModel.getFIO() + " в справочник выполнилась с ошибкой";
                }
                printError(e);
            }
        }
    }

    public void savePassport(Passport passport){
        if (passport != null && passport.getPassportId() != null){
            entityManager.merge(passport);
            entityManager.flush();
        }
    }

    public void addPassportToDebtor(){
//        passportList.add(new Passport());

        if (debtorModel.getPassportList() == null){
            debtorModel.setPassportList(new ArrayList<Passport>());
        }

        debtorModel.getPassportList().add(new Passport());
        entityManager.flush();
    }

    public void removePassportFromDebtor(Passport passport){
        if (passport == null){
            return;
        }
        if (passport.getPassportId() != null){
//            Passport passportEntity = entityManager.find(Passport.class, passport.getPassportId());
//            entityManager.refresh(passportEntity);
//            entityManager.flush();
//            entityManager.remove(passport);
//            entityManager.flush();
//            entityManager.refresh(debtorModel);
//        }
//        else {
            debtorModel.getPassportList().remove(passport);
            entityManager.flush();

            entityManager.remove(passport);
            entityManager.flush();
        }
    }

    public Boolean getUpdateMode() {
        return isUpdateMode;
    }

    public void setUpdateMode(Boolean isUpdateMode) {
        this.isUpdateMode = isUpdateMode;
    }

    public void setDebtorModel(Debtor debtorModel) {
        this.debtorModel = debtorModel;
        isUpdateMode = Boolean.TRUE;
        //this.debtorModel = debtorModel;
    }

    public Debtor getDebtorModel() {
        if (debtorModel != null && debtorModel.getDebtorId() != null && !entityManager.contains(debtorModel)){
            debtorModel = entityManager.find(Debtor.class, debtorModel.getDebtorId());
            entityManager.refresh(debtorModel);
        }
        return debtorModel;
    }

    public List<Debtor> getAllDebtors(){
        return entityManager
                .createQuery("select d from Debtor d ")
                .getResultList();
    }

    public DebtorListSort getDebtorListSort() {
        return debtorListSort;
    }

    public void setDebtorListSort(DebtorListSort debtorListSort) {
        this.debtorListSort = debtorListSort;
    }

    public DebtorListFilter getDebtorListFilter() {
        return debtorListFilter;
    }

    public void setDebtorListFilter(DebtorListFilter debtorListFilter) {
        this.debtorListFilter = debtorListFilter;
    }

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public int getRows() {
        return rows;
    }

    public void setRows(int rows) {
        this.rows = rows;
    }

    public class DebtorListSort implements Serializable{
        private SortOrder lastNameOrder = SortOrder.unsorted;
        private SortOrder firstNameOrder = SortOrder.unsorted;
        private SortOrder middleNameOrder = SortOrder.unsorted;
        private SortOrder birthdayOrder = SortOrder.unsorted;

        public SortOrder getLastNameOrder() {
            return lastNameOrder;
        }

        public void setLastNameOrder(SortOrder lastNameOrder) {
            this.lastNameOrder = lastNameOrder;
        }

        public SortOrder getFirstNameOrder() {
            return firstNameOrder;
        }

        public void setFirstNameOrder(SortOrder firstNameOrder) {
            this.firstNameOrder = firstNameOrder;
        }

        public SortOrder getMiddleNameOrder() {
            return middleNameOrder;
        }

        public void setMiddleNameOrder(SortOrder middleNameOrder) {
            this.middleNameOrder = middleNameOrder;
        }

        public SortOrder getBirthdayOrder() {
            return birthdayOrder;
        }

        public void setBirthdayOrder(SortOrder birthdayOrder) {
            this.birthdayOrder = birthdayOrder;
        }

        public void sortByLastName(){
            firstNameOrder = SortOrder.unsorted;
            middleNameOrder = SortOrder.unsorted;
            birthdayOrder = SortOrder.unsorted;
            if (lastNameOrder.equals(SortOrder.ascending)){
                lastNameOrder = SortOrder.descending;
            } else {
                lastNameOrder = SortOrder.ascending;
            }
        }

        public void sortByFirstName(){
            lastNameOrder = SortOrder.unsorted;
            middleNameOrder = SortOrder.unsorted;
            birthdayOrder = SortOrder.unsorted;
            if (firstNameOrder.equals(SortOrder.ascending)){
                firstNameOrder = SortOrder.descending;
            } else {
                firstNameOrder = SortOrder.ascending;
            }
        }

        public void sortByMiddleName(){
            lastNameOrder = SortOrder.unsorted;
            firstNameOrder = SortOrder.unsorted;
            birthdayOrder = SortOrder.unsorted;
            if (middleNameOrder.equals(SortOrder.ascending)){
                middleNameOrder = SortOrder.descending;
            } else {
                middleNameOrder = SortOrder.ascending;
            }
        }

        public void sortByBirthday(){
            lastNameOrder = SortOrder.unsorted;
            middleNameOrder = SortOrder.unsorted;
            firstNameOrder = SortOrder.unsorted;
            if (birthdayOrder.equals(SortOrder.ascending)){
                birthdayOrder = SortOrder.descending;
            } else {
                birthdayOrder = SortOrder.ascending;
            }
        }
    }

    public class DebtorListFilter implements Serializable{
        private String lastNameFilter;
        private String firstNameFilter;
        private String middleNameFilter;

        public String getLastNameFilter() {
            return lastNameFilter;
        }

        public void setLastNameFilter(String lastNameFilter) {
            this.lastNameFilter = lastNameFilter;
        }

        public String getFirstNameFilter() {
            return firstNameFilter;
        }

        public void setFirstNameFilter(String firstNameFilter) {
            this.firstNameFilter = firstNameFilter;
        }

        public String getMiddleNameFilter() {
            return middleNameFilter;
        }

        public void setMiddleNameFilter(String middleNameFilter) {
            this.middleNameFilter = middleNameFilter;
        }
    }
}
